package com.jl.core.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jl.config.PageModel;
import com.jl.constants.UserRole;
import com.jl.core.mapper.*;
import com.jl.core.model.SysExtractCash;
import com.jl.core.model.SysOperateRecord;
import com.jl.core.model.SysRecharge;
import com.jl.core.model.resp.AccountStatistic;
import com.jl.core.model.resp.OperateRecordResp;
import com.jl.core.model.resp.QueryExchangeResp;
import com.jl.core.model.resp.StatisticResp;
import com.jl.core.netty.MyWebSocketHandler;
import com.jl.core.service.CoalitionService;
import com.jl.core.util.EmailUtil;
import com.jl.enums.OperateType;
import com.jl.exception.RRException;
import com.jl.mapper.AuthMapper;
import com.jl.model.*;
import com.jl.model.gongniu.enums.Ante;
import com.jl.model.gongniu.vo.CoalitionGongNiuRoomRule;
import com.jl.model.gongniu.vo.CoalitionGongNiuRoomVo;
import com.jl.model.niuniu.enums.AdvancedOptions;
import com.jl.model.niuniu.enums.PushInjection;
import com.jl.model.niuniu.enums.SpecialCardType;
import com.jl.model.niuniu.enums.SpecialCardType2;
import com.jl.model.niuniu.vo.CoalitionNiuRoomRule;
import com.jl.model.niuniu.vo.CoalitionNiuRoomVo;
import com.jl.model.socket.RoomDetail;
import com.jl.model.vo.CoalitionVo;
import com.jl.model.vo.UserRoomVo;
import com.jl.model.vo.UserVo;
import com.jl.service.GetUserInfoService;
import com.jl.service.RoomInfoService;
import com.jl.utils.CommonUtils;
import com.jl.utils.MailBean;
import com.jl.utils.ObjectUtils;
import com.jl.utils.UserInfoContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
@Transactional
public class CoalitionServiceImpl implements CoalitionService {

    @Resource
    private CoalitionMapper coalitionMapper;
    @Resource
    private CoalitionRoomMapper coalitionRoomMapper;
    @Resource
    private AuthMapper authMapper;
    @Resource
    private GetUserInfoService getUserInfoService;
    @Resource
    private SysExtractCashMapper sysExtractCashMapper;
    @Resource
    private SysOperateRecordMapper sysOperateRecordMapper;
    @Resource
    private SysRechargeMapper sysRechargeMapper;
    @Resource
    private RoomInfoService roomInfoService;
    @Resource
    private EmailUtil emailUtil;

    @Value("${spring.mail.username}")
    private String recipient;

    @Override
    public List<CoalitionVo> getList() {
        List<CoalitionVo> list = coalitionMapper.selectCoalitionList();
        for (CoalitionVo coalitionVo : list) {
            coalitionVo.setName("牛王联盟");
            coalitionVo.setCreateUser("恭喜发财");
            coalitionVo.setRole("诚信招商");
        }
        return list;
    }

    @Override
    public void create(String name, UserVo user) {
        Coalition coalition = new Coalition();
        coalition.setCreateTime(new Date());
        coalition.setCreateUser(user.getId());
        coalition.setName(name);
        coalitionMapper.insert(coalition);
    }

    @Override
    public List<CoalitionRoomList> getRoomList(Integer coalitionId, String gameType,Integer roomId) {
        List<CoalitionRoomList> list = new ArrayList<>();
        if (!StringUtils.isEmpty(gameType)){
            switch (gameType){
                case "1":
                    selectNiuRoom(coalitionId, list,roomId);
                    break;
                case "2":
                    selectGongNiuRoom(coalitionId,list,roomId);
                    break;
            }
        }else {
            selectNiuRoom(coalitionId, list,roomId);
            selectGongNiuRoom(coalitionId,list,roomId);
        }
        return list;
    }

    @Override
    public QueryExchangeResp queryExchange() {
        UserVo user = UserInfoContext.getUser();
        User user1 = authMapper.selectByPrimaryKey(user.getId());
        QueryExchangeResp queryExchangeResp = new QueryExchangeResp();
        queryExchangeResp.setBankNo(user1.getBankNo());
        queryExchangeResp.setCoin(user1.getCoin());
        queryExchangeResp.setAlipay(user1.getAlipay());
        return queryExchangeResp;
    }

    @Override
    public void bindBank(String name, String bankNo, String bank) {
        UserVo user1 = UserInfoContext.getUser();
        User user = new User();
        user.setId(user1.getId());
        user.setBankName(name);
        user.setBankNo(bankNo);
        user.setBank(bank);
        authMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public void exchange(String coin,String bankNo,String rest) {
        UserVo user = UserInfoContext.getUser();
        User user1 = authMapper.selectUserAccountInfo(user.getId(),bankNo);
        if (user1!=null){
            String exchange = new BigDecimal(coin).multiply(new BigDecimal("0.99")).setScale(0,BigDecimal.ROUND_DOWN).toString();
            String type;
            String content;
            if (bankNo.equals(user1.getBankNo())){
                type = "1";
                content = "用户"+user.getId()+":"+user1.getBankName()+","+"申请兑现"+exchange+"元"+",银行卡账号为:"+bankNo;
            }else {
                type = "2";
                content = "用户"+user.getId()+","+"申请兑现"+exchange+"元"+",支付宝账号为:"+user1.getAlipay();
            }
            SysExtractCash sysExtractCash = new SysExtractCash();
            sysExtractCash.setUserId(user.getId());
            sysExtractCash.setBankNo(bankNo);
            sysExtractCash.setCreateTime(new Date());
            sysExtractCash.setExtractCash(new BigDecimal(coin));
            sysExtractCash.setType(type);
            sysExtractCashMapper.insertUseGeneratedKeys(sysExtractCash);
            //插入记录表
            SysOperateRecord sysOperateRecord = new SysOperateRecord();
            sysOperateRecord.setUserId(user.getId());
            sysOperateRecord.setType(OperateType.type1.getId());
            sysOperateRecord.setRemainderMoney(new BigDecimal(rest));
            sysOperateRecord.setMoney(new BigDecimal(coin));
            sysOperateRecord.setCreateTime(new Date());
            sysOperateRecordMapper.insertUseGeneratedKeys(sysOperateRecord);

            getUserInfoService.changeAccount(2,user.getId(),new BigDecimal(coin));
            //发送信息到邮箱
            String subject = "用户"+user.getId()+"申请兑现";
            emailUtil.sendSimpleMail(new MailBean(recipient,subject,content));
        }else {
            throw new RRException("账号不存在","501");
        }
    }

    @Override
    public void give(Integer userId, String coin) {
        User user1 = authMapper.selectByPrimaryKey(userId);
        if (user1==null){
            throw new RRException("用户不存在","501");
        }
        UserVo user = UserInfoContext.getUser();
        //添加记录表
        SysOperateRecord sysOperateRecord = new SysOperateRecord();
        sysOperateRecord.setCreateTime(new Date());
        sysOperateRecord.setMoney(new BigDecimal(coin));
        sysOperateRecord.setRemainderMoney(user.getCoin().subtract(new BigDecimal(coin)));
        sysOperateRecord.setType(OperateType.type3.getId());
        sysOperateRecord.setPartakeUser(userId);
        sysOperateRecord.setUserId(user.getId());
        sysOperateRecordMapper.insertUseGeneratedKeys(sysOperateRecord);

        getUserInfoService.changeAccount(2,user.getId(),new BigDecimal(coin));
        getUserInfoService.changeAccount(1,userId,new BigDecimal(coin));
    }

    @Override
    public PageModel<OperateRecordResp> queryRecord(Integer pageNumb, Integer pageSize) {
        UserVo user = UserInfoContext.getUser();
        PageHelper.startPage(pageNumb,pageSize);
        List<OperateRecordResp> list = sysOperateRecordMapper.selectRecordByUserId(user.getId());
        for (OperateRecordResp operateRecordResp : list) {
            operateRecordResp.setType(OperateType.getDescById(operateRecordResp.getType()));
        }
        PageInfo<OperateRecordResp> playerPageInfo = new PageInfo<>(list);
        PageModel<OperateRecordResp> playerPageModel = new PageModel<>(playerPageInfo);
        return playerPageModel;
    }

    @Override
    public void recharge(Integer userId, String coin) {
        User user1 = authMapper.selectByPrimaryKey(userId);
        if (user1==null){
            throw new RRException("玩家不存在","501");
        }
        UserVo user = UserInfoContext.getUser();
        if ("1".equals(user.getUserRole())){
            SysRecharge sysRecharge = new SysRecharge();
            sysRecharge.setCoin(new BigDecimal(coin));
            sysRecharge.setCreateTime(new Date());
            sysRecharge.setOperateUserId(user.getId());
            sysRecharge.setUserId(userId);
            sysRechargeMapper.insertUseGeneratedKeys(sysRecharge);
            getUserInfoService.changeAccount(1,userId,new BigDecimal(coin));
        }else {
            throw new RRException("无充值权限","501");
        }
    }

    @Override
    public void deleteRoom() {
        List<CoalitionRoom> roomIds = coalitionMapper.selectDeleteRoom();
        for (CoalitionRoom room : roomIds) {
            roomInfoService.deleteRoom(room.getId(),room.getGameType());
        }
    }

    @Override
    public void bindAlipay(String account) {
        UserVo user1 = UserInfoContext.getUser();
        User user = new User();
        user.setId(user1.getId());
        user.setAlipay(account);
        authMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public StatisticResp statistic(Integer pageNumb, Integer pageSize,String date) {
        StatisticResp statisticResp = new StatisticResp();
        UserVo user = UserInfoContext.getUser();
        PageHelper.startPage(pageNumb,pageSize);
        List<AccountStatistic> list = sysExtractCashMapper.selectAccountStatistic(user.getId(),user.getUserRole(),date);
        PageInfo<AccountStatistic> playerPageInfo = new PageInfo<>(list);
        PageModel<AccountStatistic> playerPageModel = new PageModel<>(playerPageInfo);
        statisticResp.setAccountStatistic(playerPageModel);
        if (UserRole.管理员.getValue().equals(user.getUserRole())){
            StatisticResp statisticResp1 = sysExtractCashMapper.selectStatisticTotal();
            statisticResp.setTotalRecharge(statisticResp1.getTotalRecharge());
            statisticResp.setTotalExchange(statisticResp1.getTotalExchange());
        }
        return statisticResp;
    }

    @Override
    public String notice() {
        return roomInfoService.getNotice();
    }

    private void selectGongNiuRoom(Integer coalitionId, List<CoalitionRoomList> list ,Integer roomId){
        List<CoalitionGongNiuRoomVo> gongNiuRoom = coalitionRoomMapper.selectGongNiuRoom(coalitionId,roomId);
        for (CoalitionGongNiuRoomVo coalitionGongNiuRoomVo : gongNiuRoom) {

            CoalitionGongNiuRoomRule coalitionGongNiuRoomRule = new CoalitionGongNiuRoomRule();
            try {
                CommonUtils.setParam(coalitionGongNiuRoomVo,coalitionGongNiuRoomRule);
            } catch (Exception e) {
                e.printStackTrace();
            }
            coalitionGongNiuRoomRule.setPlay("暗牌玩法");
            CoalitionRoomList<CoalitionGongNiuRoomRule> coalitionRoomList = new CoalitionRoomList<>();
            coalitionRoomList.setCoalitionNiuRoomRule(coalitionGongNiuRoomRule);
            coalitionRoomList.setId(coalitionGongNiuRoomVo.getId());
            coalitionRoomList.setCoalitionId(coalitionGongNiuRoomVo.getCoalitionId());
            coalitionRoomList.setName(coalitionGongNiuRoomVo.getName());
            coalitionRoomList.setGameType(coalitionGongNiuRoomVo.getGameType());
            String str = coalitionGongNiuRoomVo.getAdvancedOptions().contains(com.jl.model.gongniu.enums.AdvancedOptions.type5.getId())==true?"有花牌":"无花牌";
            coalitionRoomList.setDesc("无限斗公牛-"+str);
            RoomDetail detail = MyWebSocketHandler.gongNiuRoomDetailMap.get(coalitionGongNiuRoomVo.getId());
            if (detail!=null && CollectionUtil.isNotEmpty(detail.getUserInfo())){
                List<UserRoomVo> userRoomVos = ObjectUtils.convertList(detail.getUserInfo().values(), UserRoomVo.class);
                coalitionRoomList.setUserList(userRoomVos);
            }
            coalitionRoomList.setArgs1(coalitionGongNiuRoomVo.getFirstBank().toString());
            coalitionRoomList.setArgs2(CommonUtils.getEnumDescById(Ante.class,coalitionGongNiuRoomVo.getAnte(),"getDesc"));
            coalitionRoomList.setArgs3(coalitionGongNiuRoomVo.getIntoCoin().toString());
            list.add(coalitionRoomList);
        }
    }

    private void selectNiuRoom(Integer coalitionId, List<CoalitionRoomList> list,Integer roomId) {
        List<CoalitionNiuRoomVo> niuRoom = coalitionRoomMapper.selectNiuRoom(coalitionId,roomId);
        for (CoalitionNiuRoomVo coalitionNiuRoomVo : niuRoom) {

            String play = AdvancedOptions.typeStr(coalitionNiuRoomVo.getAdvancedOptions());
            CoalitionRoomList<CoalitionNiuRoomRule> coalitionRoomList = new CoalitionRoomList<>();
            CoalitionNiuRoomRule coalitionNiuRoomRule = new CoalitionNiuRoomRule();
            try {
                CommonUtils.setParam(coalitionNiuRoomVo,coalitionNiuRoomRule);
                List<ParamVo> list2 = new ArrayList<>();
                if (("1,2".contains(coalitionNiuRoomRule.getFlopRule().getId()))){
                    SpecialCardType[] values = SpecialCardType.values();
                    for (SpecialCardType value : values) {
                        setSpecialCardType(coalitionNiuRoomVo, list2, value.getId(), value.getDesc());
                    }
                }else {
                    SpecialCardType2[] values = SpecialCardType2.values();
                    for (SpecialCardType2 value : values) {
                        setSpecialCardType(coalitionNiuRoomVo, list2, value.getId(), value.getDesc());
                    }
                }
                coalitionNiuRoomRule.setSpecialCardType(list2);
            } catch (Exception e) {
                e.printStackTrace();
            }
            coalitionNiuRoomRule.setPlay(play);
            coalitionRoomList.setCoalitionNiuRoomRule(coalitionNiuRoomRule);
            try {
                CommonUtils.transfer(coalitionNiuRoomVo);
            } catch (Exception e) {
                e.printStackTrace();
            }
            coalitionRoomList.setDesc("牛牛-"+ play);
            coalitionRoomList.setId(coalitionNiuRoomVo.getId());
            coalitionRoomList.setGameType(coalitionNiuRoomVo.getGameType());
            coalitionRoomList.setName(coalitionNiuRoomVo.getName());
            coalitionRoomList.setCoalitionId(coalitionNiuRoomVo.getCoalitionId());
            RoomDetail detail = MyWebSocketHandler.niuRoomDetailMap.get(coalitionNiuRoomVo.getId());
            if (detail!=null && CollectionUtil.isNotEmpty(detail.getUserInfo())){
                List<UserRoomVo> userRoomVos = ObjectUtils.convertList(detail.getUserInfo().values(), UserRoomVo.class);
                coalitionRoomList.setUserList(userRoomVos);
            }
            coalitionRoomList.setArgs1(coalitionNiuRoomVo.getBets().split("/")[0]);
            coalitionRoomList.setArgs2(String.valueOf(PushInjection.typeStr(coalitionNiuRoomVo.getPushInjection())));
            coalitionRoomList.setArgs3(coalitionNiuRoomVo.getIntoCoin().toString());

            list.add(coalitionRoomList);
        }
    }

    private void setSpecialCardType(CoalitionNiuRoomVo niuNiuParamDto, List<ParamVo> list, String id, String desc) {
        if (!StringUtils.isEmpty(niuNiuParamDto.getSpecialCardType())) {
            String[] split = niuNiuParamDto.getSpecialCardType().split(",");
            for (String s : split) {
                if (id.equals(s)) {
                    ParamVo paramVo = new ParamVo(id, desc);
                    list.add(paramVo);
                }
            }
        }
    }
}
